package edu.cmu.aes.project1.app1;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Rohan
 */
import java.net.*;
import java.io.*;
import java.util.*;
import java.util.regex.*;
import java.lang.reflect.Array;

import org.w3c.dom.*;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import java.io.FileOutputStream;

public class Application1 {

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String[] args) throws Exception

	{
		URL bikereview = new URL("http://bikereviews.com/road-bikes/");
		BufferedReader con = new BufferedReader(
				new InputStreamReader(System.in));
		String page = methodurl(bikereview);
		String buff = null;
		int i = 0, j = 0;
		String flag = "y";

		String manufacturer = null;
		String[] reg_temp = new String[2];
		reg_temp[0] = null;
		reg_temp[1] = null;
		Hashtable url_list = new Hashtable();

		Pattern p = Pattern.compile("href=\"(.*?)\">(.*?Road Bikes)</a></td>");
		Matcher mat = p.matcher(page);
		while (mat.find()) {
			reg_temp[0] = mat.group(2);
			reg_temp[1] = mat.group(1);
			url_list.put(j, reg_temp);
			reg_temp = new String[2];
			j++;
			// url_list.put(mat.group(1), mat.group(2));
		}
		// System.out.println(url_list.size());

		do {
			
			Hashtable model_list = new Hashtable();
			System.out.println("***List of Manufacturers***\n");

			for (i = 0; i < url_list.size(); i++) {
				reg_temp = (String[]) url_list.get(i);
				System.out.println(i + 1 + ". "
						+ ((String[]) url_list.get(i))[0]);

			}
			System.out.print("Enter your choice: ");
			i = Integer.parseInt(con.readLine());
			// int k = 0;
			// for(k=0;k<url_list.size();k++)
			// {
			buff = ((String[]) url_list.get(i - 1))[1];
			manufacturer = ((String[]) url_list.get(i - 1))[0];
			// buff = ((String[])url_list.get(k))[1];
			// manufacturer = ((String[])url_list.get(k))[0];
			Pattern ur2010 = Pattern
					.compile("http://bikereviews.com/road-bikes/(.*)");
			Matcher mat2010 = ur2010.matcher(buff);

			mat2010.find();
			buff = buff + "2010-" + mat2010.group(1);
			System.out.println("Fetching data from bikereviews.com for "
					+ manufacturer + ". Please wait...");

			bikereview = new URL(buff);
			page = methodurl(bikereview);
			Pattern pmodels = Pattern
					.compile("href=\"(http://bikereviews.com/road-bikes/.+?2010.*?)\" title=.*?>(.*?)</a>");
			Matcher mmodels = pmodels.matcher(page);
			j = 0;
			reg_temp = new String[2];

			while (mmodels.find()) {
				reg_temp[0] = mmodels.group(2);
				reg_temp[1] = mmodels.group(1);
				model_list.put(j, reg_temp);
				reg_temp = new String[2];
				j++;
			}

			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder parser = factory.newDocumentBuilder();
			Document bikexml = parser.newDocument();

			Element manufacturert = bikexml.createElement("manufacturer");
			manufacturert.setAttribute("name", manufacturer);

			manufacturert.setAttribute("year", "2010");
			bikexml.appendChild(manufacturert);

			for (j = 0; j < model_list.size(); j++) {
				bikereview = new URL(((String[]) model_list.get(j))[1]);
				// System.out.println(((String[])model_list.get(j))[1]);
				page = methodurl(bikereview);

				Element modelt = bikexml.createElement("model");
				modelt.setAttribute("name", ((String[]) model_list.get(j))[0]);
				String modname = (((String[]) model_list.get(j))[0])
						.replaceAll("\\(|\\)", "");

				// constructing the xml

				// price
				String price = null;
				Pattern pricep = Pattern.compile("\\$([0-9,\\.]+)");
				Matcher pricem = pricep.matcher(page);
				if (pricem.find())
					price = ((pricem.group(1)).replace(",", "")).replaceAll(
							"\\.$", "");
				else
					price = "n/a";

				// price element
				Element pricet = bikexml.createElement("price");
				Text price_text = bikexml.createTextNode(price);
				pricet.appendChild(price_text);
				modelt.appendChild(pricet);

				// score
				String score = null;
				Pattern scorep = Pattern
						.compile("average: <strong>(.+?)</strong> out of 5");
				Matcher scorem = scorep.matcher(page);
				if (scorem.find())
					score = scorem.group(1);
				else
					score = "No rating";

				// rating element
				Element ratingt = bikexml.createElement("rating");
				Element scoret = bikexml.createElement("score");
				Text score_text = bikexml.createTextNode(score);
				scoret.appendChild(score_text);
				ratingt.appendChild(scoret);

				// Votes
				String votes = null;
				Pattern votesp = Pattern.compile(
						"\\(<strong>(.*?)</strong> votes", Pattern.DOTALL);
				Matcher votesm = votesp.matcher(page);
				if (votesm.find())
					votes = votesm.group(1);
				else
					votes = "0";

				// votes element
				Element votest = bikexml.createElement("votes");
				Text votes_text = bikexml.createTextNode(votes);
				votest.appendChild(votes_text);
				ratingt.appendChild(votest);

				modelt.appendChild(ratingt);

				// type
				Element typet = bikexml.createElement("type");
				Text type_text = bikexml.createTextNode("Road Bike");
				typet.appendChild(type_text);
				modelt.appendChild(typet);

				// frameset
				Element frameset = bikexml.createElement("frameset");
				Pattern framesetp = Pattern.compile(modname
						+ " Frame(.*?)<strong>", Pattern.DOTALL);
				Pattern framesetq = Pattern.compile("Frame(.*?)<strong>",
						Pattern.DOTALL);
				Matcher framesetm = framesetp.matcher(page);
				Matcher framesetr = framesetq.matcher(page);
				String buffer = null;
				if (framesetm.find())
					buffer = framesetm.group(1);
				else {
					framesetr.find();
					buffer = framesetr.group(1);
				}
				// System.out.println(buffer);
				// con.readLine();
				Hashtable framesetlist = regexer(buffer);

				for (i = 0; i < framesetlist.size(); i++) {
					// System.out.println(i);
					Element elementt = bikexml.createElement("element");
					elementt.setAttribute("name",
							((String[]) framesetlist.get(i))[0]);
					Text frametext = bikexml
							.createTextNode(((String[]) framesetlist.get(i))[1]);
					elementt.appendChild(frametext);
					frameset.appendChild(elementt);
				}

				modelt.appendChild(frameset);

				// Wheels
				Element wheels = bikexml.createElement("wheels");
				Pattern wheelsp = Pattern.compile(modname
						+ " Wheels(.*?)<strong>", Pattern.DOTALL);
				Pattern wheelsp2 = Pattern.compile("Wheels(.*?)<strong>",
						Pattern.DOTALL);
				Matcher wheelsm = wheelsp.matcher(page);
				Matcher wheelsm2 = wheelsp2.matcher(page);
				String bufferw = null;
				if (wheelsm.find())
					bufferw = wheelsm.group(1);
				else {
					wheelsm2.find();
					bufferw = wheelsm2.group(1);
				}
				Hashtable wheelslist = regexer(bufferw);

				for (i = 0; i < wheelslist.size(); i++) {
					// System.out.println(i);
					Element elementt = bikexml.createElement("element");
					elementt.setAttribute("name",
							((String[]) wheelslist.get(i))[0]);
					Text wheelstext = bikexml
							.createTextNode(((String[]) wheelslist.get(i))[1]);
					elementt.appendChild(wheelstext);
					wheels.appendChild(elementt);
				}

				modelt.appendChild(wheels);

				// Drivetrain
				Element drivetrain = bikexml.createElement("drivetrain");
				Pattern drivetrainp = Pattern.compile(modname
						+ " Drivetrain(.*?)<strong>", Pattern.DOTALL);
				Pattern drivetrainp2 = Pattern.compile(
						"Drivetrain(.*?)<strong>", Pattern.DOTALL);
				Matcher drivetrainm = drivetrainp.matcher(page);
				Matcher drivetrainm2 = drivetrainp2.matcher(page);
				String bufferd = null;
				if (drivetrainm.find())
					bufferd = drivetrainm.group(1);
				else {
					drivetrainm2.find();
					bufferd = drivetrainm2.group(1);
				}
				Hashtable drivetrainlist = regexer(bufferd);

				for (i = 0; i < drivetrainlist.size(); i++) {
					// System.out.println(i);
					Element elementt = bikexml.createElement("element");
					elementt.setAttribute("name",
							((String[]) drivetrainlist.get(i))[0]);
					Text drivetraintext = bikexml
							.createTextNode(((String[]) drivetrainlist.get(i))[1]);
					elementt.appendChild(drivetraintext);
					drivetrain.appendChild(elementt);
				}

				modelt.appendChild(drivetrain);

				// Components
				Element components = bikexml.createElement("components");
				Pattern componentsp = Pattern.compile(modname
						+ " Components</strong>(.*?)(<strong>|<script)",
						Pattern.DOTALL);
				Matcher componentsm = componentsp.matcher(page);

				Pattern componentsp2 = Pattern.compile(
						"Components</strong>(.*?)(<strong>|<script)",
						Pattern.DOTALL);
				Matcher componentsm2 = componentsp2.matcher(page);
				String bufferc = null;
				if (componentsm.find())
					bufferc = componentsm.group(1);
				else {
					componentsm2.find();
					bufferc = componentsm2.group(1);
				}
				Hashtable componentslist = regexer(bufferc);

				for (i = 0; i < componentslist.size(); i++) {
					// System.out.println(i);
					Element elementt = bikexml.createElement("element");
					elementt.setAttribute("name",
							((String[]) componentslist.get(i))[0]);
					Text componentstext = bikexml
							.createTextNode(((String[]) componentslist.get(i))[1]);
					elementt.appendChild(componentstext);
					components.appendChild(elementt);
				}

				modelt.appendChild(components);

				manufacturert.appendChild(modelt);

			}

			TransformerFactory tranFactory = TransformerFactory.newInstance();
			Transformer aTransformer = tranFactory.newTransformer();

			String filePath = "output/app1/";
			File fileDirectory = new File(filePath);
			if (!fileDirectory.exists())
				fileDirectory.mkdirs();

			Source src = new DOMSource(bikexml);
			Result dest = new StreamResult(new FileOutputStream(filePath
					+ manufacturer + ".xml"));
			aTransformer.transform(src, dest);

			System.out
					.println("Do you wish to fetch another manufacturers data?");
			System.out
					.print("Enter Y/y to continue, any other value to quit: ");
			flag = con.readLine();

		} while (flag.equals("Y") || flag.equals("y"));

		// }

	}

	public static String methodurl(URL x) throws Exception {
		URLConnection conn = null;
		BufferedReader in = new BufferedReader(new InputStreamReader(
				(conn = x.openConnection()).getInputStream()));

		String line = null;
		String page = "";
		while ((line = in.readLine()) != null)
			page = page.concat(line + "\n");

		in.close();
		return page;
	}

	public static Hashtable regexer(String buffer) throws Exception {
		Hashtable elements = new Hashtable();
		String[] reg_temp = new String[2];
		int j = 0;

		Pattern framesetp = Pattern.compile("/> (.*?): (.*?)<br",
				Pattern.DOTALL);
		Matcher framesetm = framesetp.matcher(buffer);

		while (framesetm.find()) {
			// System.out.println(j);
			reg_temp[0] = framesetm.group(1);
			reg_temp[1] = framesetm.group(2);
			elements.put(j, reg_temp);
			reg_temp = new String[2];
			j++;
		}

		return elements;

	}

}
